#!/usr/bin/env python

import smtplib
import imaplib
import mimetypes
import email
from email.Header import decode_header
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.MIMEAudio import MIMEAudio
from email.MIMEImage import MIMEImage
from email.Encoders import encode_base64


class SzMail(object):

    def __init__(self):
        self.server_port=993
        self.list_response_pattern = re.compile(r'\((?P<flags>.*?)\) "(?P<delimiter>.*)" (?P<name>.*)')
        self.list_status_pattern = re.compile(
                r'(?P<MESSAGES>.*?) "(?P<UIDVALIDITY>.*)" (?P<RECENT>.*) ')
        config = ConfigParser.ConfigParser()
        config.read(os.path.join("D:/Emails/conf/mail.cfg"))
        self.hostname = config.get('server', 'hostname')
        self.username = config.get('account', 'username')
        self.password = config.get('account', 'password')


    def login(self):
        self.conn = imaplib.IMAP4_SSL(self.hostname,self.server_port)
        self.conn.login(self.username, self.password)

    def logout(self):
        self.conn.logout()


    def _parse_list_response(self,line):
        flags, delimiter, mailbox_name = self.list_response_pattern.match(line).groups()
        mailbox_name = mailbox_name.strip('"')
        return (flags, delimiter, mailbox_name)


    def list_folder_status(self):
        typ, data = self.conn.list()
        result = []
        for line in data:
            flags, delimiter, mailbox_name = self._parse_list_response(line)
            status = self.conn.status(mailbox_name, '(MESSAGES UIDVALIDITY RECENT UNSEEN)')
            # status content : between ()
            content = status[1][0]
            print content
            status_data = content[content.find("(") + 1 : -1].split()
            for index, value in enumerate(status_data) :
                if value == "MESSAGES" :
                    msgs = status_data[index+1]
                elif value == "UIDVALIDITY" :
                    uid = status_data[index+1]
                elif value == "RECENT" :
                    recent = status_data[index+1]
                elif value == "UNSEEN" :
                    unseen = status_data[index+1]
            result.append((mailbox_name,msgs,uid,recent,unseen))
        return result


    def test(self):
        self.conn.select('INBOX', readonly=True)

        typ, msg_data = self.conn.fetch("52", '(RFC822)')
        for response_part in msg_data:
            if isinstance(response_part, tuple):
                msg = email.message_from_string(response_part[1])

                for item in msg.keys():
                    vals=[]
                    for val,charset in decode_header(msg[item]) :
                        if charset :
                            if charset == "gb2312" :
                                charset = "gbk"
                            val = unicode(val,charset,"replace")
                        vals.append(val)
                    print item ,":     ", ",".join(vals)
                    print '+'*60

                print "parse result"
                print '+'*60
                self.parse_mail(msg)


                #for header in [ 'subject', 'to', 'from' ]:
                #    d_text=decode_header(msg[header])[0][0]
                #    print '%-8s: %s' % (header.upper(), d_text)

    def search_mail(self, criteria):
            self.conn.select('INBOX', readonly=True)
            typ, msg_ids = self.conn.search(None, criteria)
            print typ,msg_ids
            if typ !='OK' : return
            for id in msg_ids[0].split() :
                if id == "" : continue
                try :
                    typ, msg_data = self.conn.fetch(id, '(RFC822)')
                    for response_part in msg_data:
                        if isinstance(response_part, tuple):
                            msg = email.message_from_string(response_part[1])
                            for header in [ 'subject', 'to', 'from' ]:
                                d_text=decode_header(msg[header])[0][0]
                                print '%-8s: %s' % (header.upper(), d_text)
                            self.parse_mail(msg)
                except Exception , e:
                    print e

    def parse_mail(self,msg):
        for par in msg.walk():
            if par.is_multipart(): continue
            print '+'*60
            name = par.get_param("name")
            if name:
                h = email.Header.Header(name)
                dh = email.Header.decode_header(h)
                fname = dh[0][0]
                print 'attachment:', fname
                data = par.get_payload(decode=True)
                try:
                    f = open(fname, 'wb')
                except:
                    print 'invalid char'
                    f = open('aaaa', 'wb')
                f.write(data)
                f.close()
            else:
                print par.get_content_type()
                email_text= par.get_payload(decode=True)
                charset = par.get_content_charset()
                if charset == "gb2312":
                    charset = "gbk"
                if charset :
                    print email_text.decode(charset)
                else :
                    print email_text

    def sendMail(subject, text, *attachmentFilePaths):
        gmailUser = 'sadf@gmail.com'
        gmailPassword = 'asdf'
        recipient = 'test@sdf.net'

        msg = MIMEMultipart()
        msg['From'] = gmailUser
        msg['To'] = recipient
        msg['Subject'] = subject
        msg.attach(MIMEText(text))

        for attachmentFilePath in attachmentFilePaths:
            msg.attach(getAttachment(attachmentFilePath))

        mailServer = smtplib.SMTP('smtp.gmail.com', 587)
        mailServer.ehlo()
        mailServer.starttls()
        mailServer.ehlo()
        mailServer.login(gmailUser, gmailPassword)
        mailServer.sendmail(gmailUser, recipient, msg.as_string())
        mailServer.close()

        print('Sent email to %s' % recipient)

    def getAttachment(attachmentFilePath):
        contentType, encoding = mimetypes.guess_type(attachmentFilePath)

        if contentType is None or encoding is not None:
            contentType = 'application/octet-stream'

        mainType, subType = contentType.split('/', 1)
        file = open(attachmentFilePath, 'rb')

        if mainType == 'text':
            attachment = MIMEText(file.read())
        elif mainType == 'message':
            attachment = email.message_from_file(file)
        elif mainType == 'image':
            attachment = MIMEImage(file.read(),_subType=subType)
        elif mainType == 'audio':
            attachment = MIMEAudio(file.read(),_subType=subType)
        else:
            attachment = MIMEBase(mainType, subType)
        attachment.set_payload(file.read())
        encode_base64(attachment)

        file.close()
        attachment.add_header('Content-Disposition', 'attachment',   filename=os.path.basename(attachmentFilePath))
        return attachment

class MailViewer(object):
    def __init__(self):
        pass

    @staticmethod
    def runApp():
        global mailext
        if not "mailext" in  globals() :
            mailext = Notext()
        mailext.showMailFolder()

    def showMailFolder(self):
        vim.command("call SwitchToSzToolView('mailext_dir')" )
        (row, col) = vim.current.window.cursor
        selectSql="select tag_name ,count(*) from tag group by tag_name"
        rows=self.notedb.query(selectSql)
        result=[]
        for index,row in enumerate(rows):
            tag_name=row[0]
            count=row[1]
            result.append("%s(%s)" %(tag_name,count))
        output(result)
        if row > len(vim.current.buffer):
            row=len(vim.current.buffer)
        vim.current.window.cursor=(row,col)

    def showMailList(self):
        (row, col) = vim.current.window.cursor
        tag_name=vim.current.buffer[row-1]
        tag_name=tag_name[0:tag_name.find("(")]
        self.currentTag = tag_name
        self.updateNoteListView()

    def getCurrentDate(self):
        from datetime import datetime
        t=datetime.now()
        return t.strftime("%Y-%m-%d %H:%M")

